package service

import (
	"context"
	"fmt"
	"gomain/app/model"
	"strings"
	"time"

	"github.com/gogf/gf/v2/database/gdb"
	"github.com/gogf/gf/v2/frame/g"
)

var Permission = permissionService{}

type permissionService struct{}

// 获取用户的所有权限（带缓存）
func (s *permissionService) GetUserPermissions(userId int) ([]model.Permission, error) {
	var permissions []model.Permission
	cacheKey := fmt.Sprintf("user_permissions_%d", userId)

	// 尝试从缓存获取
	err := Cache.Get(cacheKey, &permissions)
	if err == nil && len(permissions) > 0 {
		return permissions, nil
	}

	// 从数据库获取
	err = g.DB().Model("permissions").
		LeftJoin("role_permissions", "permissions.id = role_permissions.permission_id").
		LeftJoin("user_roles", "role_permissions.role_id = user_roles.role_id").
		Where("user_roles.user_id = ?", userId).
		Scan(&permissions)

	if err != nil {
		return nil, err
	}

	// 设置缓存
	Cache.Set(cacheKey, permissions, time.Minute*5)
	return permissions, nil
}

// 检查用户是否有特定权限（支持通配符）
func (s *permissionService) HasPermission(userId int, permissionCode string) bool {
	permissions, err := s.GetUserPermissions(userId)
	if err != nil {
		return false
	}

	// 检查是否有超级管理员权限
	for _, p := range permissions {
		if p.Code == "*" {
			return true
		}
	}

	// 支持通配符匹配
	for _, p := range permissions {
		if matchPermission(p.Code, permissionCode) {
			return true
		}
	}

	return false
}

// 通配符权限匹配
func matchPermission(pattern, code string) bool {
	if pattern == code {
		return true
	}

	patternParts := strings.Split(pattern, ":")
	codeParts := strings.Split(code, ":")

	if len(patternParts) != len(codeParts) {
		return false
	}

	for i := 0; i < len(patternParts); i++ {
		if patternParts[i] != "*" && patternParts[i] != codeParts[i] {
			return false
		}
	}

	return true
}

// 权限组结构
type PermissionGroup struct {
	Id          int    `json:"id"`
	Name        string `json:"name"`
	Code        string `json:"code"`
	Permissions []int  `json:"permissions"`
}

// 创建权限组
func (s *permissionService) CreateGroup(group *PermissionGroup) error {
	ctx := context.Background()
	return g.DB().Transaction(ctx, func(ctx context.Context, tx gdb.TX) error {
		// 插入权限组
		res, err := tx.Model("permission_groups").Data(g.Map{
			"name": group.Name,
			"code": group.Code,
		}).Insert()
		if err != nil {
			return err
		}

		groupId, err := res.LastInsertId()
		if err != nil {
			return err
		}

		// 插入权限关联
		for _, permId := range group.Permissions {
			_, err = tx.Model("group_permissions").Data(g.Map{
				"group_id":      groupId,
				"permission_id": permId,
			}).Insert()
			if err != nil {
				return err
			}
		}

		return nil
	})
}
